查看原文
其他

【第1346期】如何更好的编写CSS

JeLewine 前端早读课 2019-05-31

前言

这篇不会很复杂,基础篇。今日早读文章由@JeLewine翻译分享。

正文从这开始~

废话不多说,咱们就开门见山吧:想写出优质的CSS代码将会是非常痛苦的。很多开发者都不想做CSS开发。我可以做你想做的一切,但是,除了CSS!

当我在构建应用时,CSS是我挺讨厌的部分。但你无法摆脱它,对吧?我的意思是,正是因为我们如此的专注于用户体验和设计,所以现在我们才不能跳过这一部分。

在开始一个项目时,一切都很正常。你有一些CSS选择器:.title input #app,这看起来非常的简单。

但是当你的应用变得越来越大时,它就开始变的越来越糟糕了。你对CSS选择器感到困惑。你发现你写的像div#app .list li.item a诸如此类的东西,自己在一遍又一遍地在重复相同的代码。你把所有代码都放在文件末尾,因为你根本就不在乎。CSS像一坨shit。然后你要狗带了:500行的CSS完全没法维护。

我今天有一个小目标:让你更好的去编写CSS。我想让你回首看看自己的旧项目并发出感慨:oh,boy,我怎么能写这么一坨东西?

好吧,你可能会想,你说的有道理。但是CSS框架呢?这就是他们的用法,不是吗?这就是我们编写好CSS代码的方法。

是的没错,不过这样还是会有一些缺点:

  • 它往往会带来平凡的设计

  • 想要定制或跳出CSS框架会变的困难

  • 在使用它们之前,你必须先学习它们

不过毕竟,你已经开始在看这篇文章了。这一定是有原因的,不是吗?所以,不用多说了,让我们开始学习如何更好的编写CSS吧。

注意:这不是关于如何设计优雅应用程序的文章。它是关于学习如何编写和组织可维护的CSS代码的。

SCSS

在这篇文章里我将会用SCSS作为例子。

SCSS是一个CSS的预处理器。简单来说,它是一个CSS的超集:他为CSS添加了一些很酷的功能,例如变量,嵌套,导入和mixins。

我将先谈谈我们立即会使用到哪些功能。

变量

通过SCSS,你可以使用变量了。它带来的主要好处就是可复用性。我们假设你的应用有一组颜色。你的主色调是蓝色。

所以你的应用到处都是蓝色:按钮的背景颜色,标题的颜色,链接。蓝色无处不在。

突然之间,你不喜欢蓝色。你更喜欢绿色了。

  • 没有变量:更改所有使用了蓝色的地方

  • 使用变量:只需更改变量


// 声明变量
$primary
-color: #0099ff;
// 引入变量
h1
{
 color
: $primary-color;
}
嵌套

你还可以使用SCSS来嵌套代码。看一下下面的例子:

h1 {
 font
-size: 5rem;
 color
: blue;
}
h1 span
{
 color
: green;
}

可以变成下面这样:

h1 {
 font
-size: 5rem;
 color
: blue;
 span
{
   color
: green;
 
}
}

更具有可读性,不是吗?使用嵌套来编写复杂选择器所花费的时间更少。

局部文件和引入

出于可维护性和可读性方面的考虑,我们不可能将所有代码保存在一个大文件中。在试验或构建小型应用程序时,这么做也许可以满足你的需求,但在更专业的情况下…请不要这么做。不过幸运的是,SCSS允许我们这样做。

您可以通过使用前置下划线命名文件的方式来创建局部文件:_animations.scss,_base.scss,_variables.scss等。

至于引入,我们可以使用@import命令。例如,下面这样是你可以做的:

// _animations.scss
@keyframes appear {
 
0% {
   opacity
: 0;
 
}
 
100% {
   opacity
: 1;
 
}
}
// header.scss
@import "animations";
h1
{
 animation
: appear 0.5s ease-out;
}

看到这里,你可能会认为这里是不是搞错了。应该是_animations.scss而不是animations。

不。当你用这种方式命名时,scss可以很聪明的知道你正在讨论一个局部文件。

以上就是我们所需要了解到的变量,嵌套,局部文件和引入。SCSS还有一些其他功能,像是mixins,继承指令(@for,@if,…)之类的,不过我今天不会在这里介绍他们了。

如果你想了解更多的信息,可以查看他们文档。他们写的很不错,非常容易理解。

组织CSS代码:BEM方法论

我已经记不清有多少次在我的CSS课程里用到这些名称了。你懂的:.button,.page-1,.page-2,.custom-input。

我们其实经常不知道该如何去命名。然而这是非常重要的。如果你正在构建一个应用程序,并且由于某些原因决定将其搁置几个月,该怎么办?或者更糟糕的是,如果有人要交接该项目怎么办?如果你的CSS代码没有一个正确命名,那么很难一目了然地知道你在说什么。

BEM帮我们解决了这个问题。BEM是一种命名约定,代表着块元素修饰符【译者注:原文为Block Element Modifier。在中文前端圈内发现大部分文章都将block直译为”块”,其实译者个人觉得翻译为”模块”可能会让人更好理解一点。不过本文还是选择和已有译法保持一致】。

这种方法可以使我们的代码结构化,更加模块化和可复用。现在让我来解释什么是块,元素和修饰符。

我们可以把“块”视为组件。你还记得小时候玩的乐高积木吗?【译者注:小时候没玩过,现在我也玩不起…】ok,让我们回到过去。

你会如何建造一个简单的房子?你需要一个窗户,一个屋顶,一扇门,一些墙壁,就是这样。那些是我们的块。他们各自有各自的作用。

命名:块名称:.block样例:.card,.form,.post,.user-navigation

元素

现在,你将如何用你的乐高去搭一个窗户呢?这发现其中也许有一些看起很像边框,当你把四个边框组装在一起时,一个窗户就搭好啦。那就是我们的元素。它们是“块”的一部分,它们是构建“块”的必要条件。但是,当它们离开块时就没有用了。

命名:块名称 + _ + 元素名:.block_element
样例:.post_author,.post_date,.post_text

修饰符

现在你已经搭起了一个窗户,不过也许你想要的是一个绿色的或小的。这些就是修饰符。它们是“块”或“元素”上的标志,它们用于改变行为和表现等。

命名:块名称或元素名 + - + 修饰名:.block_element-modifier, .block-modifier
样例:.post-important,.post_btn-disabled

一些笔记
  • 当您使用BEM时,你为类命名,也只能是为类命名。没有ID,没有标签。只有类。

  • 块/元素可以嵌套到其他块/元素中,但它们必须要能完全独立。记住这个词:独立。因此

  • 请不要因为你想将按钮放在标题下就将margin写在按钮上,否则您的按钮将与您的标题完全绑定。请改用其他公用类来代替这个操作。

  • 是的,你的HTML文件将会过载。但不要担心,与BEM带给您带来的好处相比,这是一个小小的缺点。

一个例子

下面是一个对你的小练习。转到你最喜欢或最常用的网站,并尝试使用BEM。

例如,下面就是我在Google商店中的想象:

轮到你了。要保持好奇人们如何可以做的更好。你必须自己去搜索,尝试和创造,这样才能更好的贴合你自己的需求。

将它们合在一起

你会发现下面的一些例子充分的展示了BEM的功力。

<!--html-->
<div class="post">
 
<span class="post__author">Thomas</span>    
 
<span class="post__date">3 minutes ago</span>
 
<p class="post__text">
   Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam sit voluptatem aut quis quisquam veniam delectus sequi maxime ullam, inventore blanditiis quia commodi maiores fuga, facere quaerat doloremque in. Nisi!  
</p>
</div>
<div class="post mt-large post--important">
 
<span class="post__author">Thomas</span>    
 
<span class="post__date">2 hours ago</span>
 
<p class="post__text">
   Voluptatem incidunt autem consequatur neque vitae aliquam, adipisci voluptatum. Ipsum excepturi dolores exercitationem rem ab similique consequatur nesciunt, tempora aut vel unde.  
</p>
</div>
<!--SCSS-->
.post {  display: inline-block;  padding: 1rem;  background-color: #ccc;  border: 1px solid #222;  border-radius: 5px;  &--important {    background-color: yellow;  }  &__author {    font-size: 1.2rem;    font-weight: bold;    color: blue;  }  &__date {    float: right;  }  &__text {    line-height: 2rem;    font-size: 1.3rem;  } }

<!--html-->
<div>
 
<button class="btn">
   Click me  
</button>
 
<button class="btn btn--danger">
   Danger  
</button>
 
<button class="btn btn--success">
   Success  
</button>
 
<button class="btn btn--small">
   Small  
</button>
 
<button class="btn btn--big">
   Big  
</button>
 
<button class="btn btn--border">
   Border  
</button>
</div>
<!--SCSS-->
.colors {  font-size: 1.5rem;  font-family: sans-serif; } .btn {    background-color: #FF6B93;    color: #fff;    text-transform: uppercase;    padding: 1.5rem 2.5rem;    border-radius: 4px;    transition: all .2s;    font-size: 1.3rem;    border: none;    letter-spacing: 2px;    cursor: pointer;  &:hover {    background-color: #D15879;  }  &:focus {    outline: none;  }  &--danger {    background-color: #FF3B1A;    &:hover {      background-color: #D43116;    }  }  &--success {    background-color: #00D123;    &:hover {      background-color: #00AB1D;    }  }  &--small {    padding: 1rem 2rem;    font-size: 1rem;  }  &--big {    padding: 1.8rem 4.5rem;    font-size: 1.7rem;  }  &--border {    background-color: #fff;    color: #FF6B93;    border: 1px solid #FF6B93;    &:hover {      background-color: #FF6B93;      color: #fff;    }  } }

组织CSS文件:7-1模式

你坚持看到这儿了?优秀! 现在让我们看看如何组织CSS文件。这部分将真正帮助你提高工作效率,并能够让你立即找到必须要修改的CSS代码的位置。

为此,我们将了解7-1模式。

你可能会想这是个什么玩意【译者注:711便利店?233】。

相信我,这很简单。你只须遵守下面2条规则:

  • 将所有的局部文件写入7个不同的文件夹中。

  • 将它们全部导入位于根级别的一个main.scss文件中。

就是这样。

7个文件夹

base:在这里,把所有的脚手架代码都放进去。通过脚手架,我指的是每次启动一个新项目时要写的所有CSS代码。例如:排版规则、动画、公用(公用类,我指的是margin-right-large,text-center,……之类的类)。

components:这里的名称是明确的。此文件夹包含用于构建页面的所有组件,如按钮,表单,swipers,弹出窗口等。

layout:用于布局页面的不同部分。也就是说,页眉,页脚,导航,自己的网格等等。

pages:你有时可能会有一个页面会具有一些自己特定的样式。将它们与那些通用的样式分开,然后将它们放在pages文件夹中。

themes:如果你的应用有不同的主题(黑暗模式,管理员模式等),请将它们放在此文件夹中。

abstracts:将所有函数与变量和mixin一起放在这里。

vendors:现在有什么项目是没有依赖外部库的?在vendor文件夹中放入所有不依赖于你的文件。你可能希望在此处添加Font Awesome文件,Bootstrap和类似的东西。
主文件

在这里导入你所有的partials。

@import abstracts/variables;
@import abstracts/functions;
@import base/reset;
@import base/typography;
@import base/utilities;
@import components/button;
@import components/form;
@import components/user-navigation;
@import layout/header;
@import layout/footer;
...

是的。这看起很庞大。不过我知道你会这么想,这种架构适用于更大的项目,而不是小的。这里有一个适用于较小项目的版本。

首先,你不需要vendors文件夹。只需将所有外部CSS代码放置在头文件中的链接标签中即可。然后你可以跳过themes文件夹,因为你的应用可能只有一个主题。最后,你的页面不会有很多特定的样式,所以你也可以跳过pages这个页面。太好了,只剩下4个文件夹了!

接下来,你又两个选择:

  1. 你希望你的CSS代码组织遵循7-1模式,因此你保留了abstact、components、layout和base。

  2. 你更喜欢有一个大文件夹,把所有的局部文件和你的main.scss文件放在一起。所以你会产生以下类似的东西:

sass/
 _animations
.scss
 _base
.scss
 _buttons
.scss
 _header
.scss
 
...
 _variables
.scss
 main
.scss

这完全取决于你自己。

你把我说服了!但是我该怎么用呢?我的意思是,浏览器并不支持SCSS,不是吗?

说的好!现在到了我们的最后一步了。我们将学习如何将SCSS文件编译成CSS。

从SCSS到CSS

为此,你需要先安装Node.js和NPM(或Yarn)

我们将使用一个名为node-sass的包,它能够帮我们将.scss文件编译为.css文件。

它的CLI(命令行界面)相当容易使用:

node-sass <input> <output> [options]

node-sass提供了多种选项,不过我们只需要两个就够了:

  • -w: 观察目录或文件。这意味着node-sass能够观察到代码中的任何更改。一旦更改发生时,它会自动编译为CSS。 这在开发时非常有用。

  • —output-style:CSS文件的输出模式是什么。它可以是以下值之一:nested|expanded|compact|compressed。我们将使用它来构建你的CSS文件。

如果你是一个有好奇心的人(我希望你是,开发人员应该保持好奇!),可以到这里查看完整的文档。

现在我们已经知道了我们将使用哪些工具。接下来的事就非常简单了。只要跟着下面的步骤走:

创建你的项目:mkdir my-app && cd my-app- 初始化:npm init- 添加node-sass库:npm install node-sass —save-dev- 创建你的文件夹,你的index.html和你的main.scss文件:

touch index.html
mkdir
-p sass/{abstracts,base,components,layout} css
cd sass
&& touch main.scss

修改在package.json中你的脚本命令:

{
 
...
 
"scripts": {
   
"watch:scss": "node-sass sass/main.scss css/style.css -w",
   
"build:scss": "node-sass sass/main.scss css/style.css --output
style compressed"

 
},
 
...
}

将包括那些已编译的CSS文件的引用链接添加到你的index.html文件的head标签中:

<!DOCTYPE html>
<html lang=”en”>
<head>
 
<meta charset=”UTF-8">
 
<meta name=”viewport” content=”width=device-width, initial-scale=1.0">
 
<meta http-equiv=”X-UA-Compatible” content=”ie=edge”>
 
<link rel=”stylesheet” href=”css/style.css”>
 
<title>My app</title>
</head>
<body>
 
<h1 class=”heading”>My app</h1>
</body>
</html>

就这样,已经可以跑起来了!当你开始coding并在浏览器中打开index.html时,记得运行npm run watch:scss。如果你想要压缩你的css文件,跑一下npm run build:scss就好了。

添加热更新

你可能在开发中更希望通过热更新来提高效率,而不是每次都要手动重载index.html文件。

只要跟着以下几个简单的步骤:

  • 安装live-server包:npm install -g live-server。注意:这是一个全局包

  • 添加npm-run-all包到你的项目依赖中:npm install npm-run-all —save-dev。它能够让你同时运行多个脚本命令。

  • 添加下面的命令到package.json中:


{
 
...
 
"scripts": {
   
"dev": "npm-run-all --parallel liveserver watch:scss ",
   
"liveserver": "live-server",
   
"watch:scss": "node-sass sass/main.scss css/style.css -w",
   
"build:scss": "node-sass sass/main.scss css/style.css --output-style compressed"
 
},
 
...

现在,当你运行npm run dev时,你可以立即看到你的修改,而且无需手动重载任何内容。太棒了,不是吗?

不过你知道更棒的是什么吗?为了方便你快速上手,我为此建了一个repo。

如果你想要知道我是如何将这些技巧应用到我的项目中的,可以查看这个repo。这里是演示结果。我希望你可以通过这个例子拥有更深的理解。

这就是今天要说的一切!现在,你已经做好了编写可维护,模块化和可复用的CSS代码的准备。

关于本文
译者:@eLewine
译文:
https://zhuanlan.zhihu.com/p/40326332
作者:@Thomas Lombart
原文:
https://medium.freecodecamp.org/how-to-get-better-at-writing-css-a1732c32a72f

最后,为你推荐


【第1288期】新的 CSS 特性正在改变网页设计


【第1254期】用CSS Houdini画一片星空

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存